unit uAdjDivForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uBaseDivForm, StdCtrls, ExtCtrls;

type
  TObjectTarget = (otRTop,otRAdj,otRBot,otVout,otVin);

  TfmAdjDivForm = class(TfmBaseDivForm)
    edP4: TLabeledEdit;
    laP4: TLabel;
    imgP4: TImage;
    imgUIn: TImage;
    imgR1: TImage;
    imgUout: TImage;
    imgR2: TImage;
    imgR3: TImage;
    edP5: TLabeledEdit;
    laP5: TLabel;
    procedure imgUoutClick(Sender: TObject);
    procedure imgP4Click(Sender: TObject);
    procedure imgP3Click(Sender: TObject);
    procedure imgP2Click(Sender: TObject);
    procedure imgR3Click(Sender: TObject);
  private
    { Private declarations }
    FObjectIndex: TObjectTarget;
    FValues: array[0..5] of single;
  protected
    function DoCheckFields: boolean; override;
    procedure FieldsChanged; override;
  public
    { Public declarations }
    class function CalcFriendlyName: string; override;
    class function RunKey: string; override;
    class procedure InvokeCalc; override;
    procedure AfterConstruction; override;
  end;

var
  fmAdjDivForm: TfmAdjDivForm;

implementation

uses uFormReg, uENoms, uLocalization;

{$R *.dfm}

{ TfmAdjDivForm }

procedure TfmAdjDivForm.AfterConstruction;
begin
  inherited;
  imgUoutClick(imgUout);
end;

function TfmAdjDivForm.DoCheckFields: boolean;
var tmp: single;
begin
  Result := false;
  if CheckField(edP1)<=0 then exit;
  
  tmp := CheckField(edP2);
  if tmp<0 then exit;
  imgP2.Visible := (not IsInE24(tmp));

  tmp := CheckField(edP4);
  if tmp<0 then exit;
  imgP4.Visible := (FObjectIndex=otVout) and (not IsInE24(tmp));

  tmp := CheckField(edP3);
  if tmp<0 then exit;
  imgP3.Visible := (FObjectIndex=otVout) and (not IsInE24(tmp));

  Result := true;
end;

procedure TfmAdjDivForm.FieldsChanged;
var tmp,rbl,rbh,vomin,vomax: single;
begin
  inherited;
  edResult.Text := getString('#global\invaliddata');
  imgRes.Visible := false;

  FValues[0] := StrToFloat(edP1.Text);
  FValues[1] := StrToFloat(edP2.Text);
  FValues[2] := StrToFloat(edP3.Text);
  FValues[3] := StrToFloat(edP4.Text);

  case FObjectIndex of
    // Vout = Vcc*(Rb/(Rt+Rb))
    otVout: begin
         if (FValues[1]+FValues[2]+FValues[3]=0) then begin
           edResult.Text := getString('#global\shortcircuit'); exit;
         end
         else
         if (FValues[1]+FValues[2] = 0) then
         else begin
           FValues[4] := FValues[0]*(FValues[2]/(FValues[1]+FValues[3]+FValues[2]));
           FValues[5] := FValues[0]*((FValues[2]+FValues[3])/(FValues[1]+FValues[3]+FValues[2]));
         end;
         
         tmp := FValues[0]/(FValues[1]+FValues[2]+FValues[3]);
         edCurr.Text := Format('%sA, %sW', [formatValue(tmp), formatValue(FValues[0]*tmp)]);
       end;
    // Rtop = Vcc*Rbot/Vout
    // Rbot = (Vcc*Rtop)/(Vcc-Vout)-Rtop
    otRAdj: begin
        vomin := CheckField(edP3);
        vomax := CheckField(edP5);
        if (vomin<0) or (vomax<=0) or (vomax<vomin) then exit;

        if (vomin>0) then
          FValues[4] := (FValues[0]*FValues[1])/(FValues[0]-vomin)-FValues[1]
        else
          FValues[4] := 0;
        FValues[5] := (FValues[0]*FValues[1])/(FValues[0]-vomax)-FValues[1];
      end;
  end;

  if (FValues[4]<>FValues[5]) then edResult.Text := Format('%.3f ... %.3f', [FValues[4], FValues[5]])
  else edResult.Text := Format('%.3f', [FValues[4]]);
end;

procedure TfmAdjDivForm.imgUoutClick(Sender: TObject);
begin
  inherited;
  LoadPictureFromRes(imgR1.Picture, 'R1');
  LoadPictureFromRes(imgR2.Picture, 'R2');
  LoadPictureFromRes(imgR3.Picture, 'R3');
  LoadPictureFromRes(imgUin.Picture, 'UIN');
  LoadPictureFromRes(imgUout.Picture, 'UOUTS');
  SetLabels('P1',getString('#global\Uin'),getString('#global\volt'));
  SetLabels('P2','R1',getString('#global\Ohm'));
  SetLabels('P3','R2',getString('#global\Ohm'));
  SetLabels('P4','R3',getString('#global\Ohm'));
  SetLabels('Result',getString('#global\Uout'),getString('#global\volt'));
  edP5.Visible := false;
  laP5.Visible := false;

  FObjectIndex := otVout;
end;

procedure TfmAdjDivForm.imgP4Click(Sender: TObject);
begin
  inherited;
  edP4.Text := Format('%f', [GetE24(CheckField(edP4))]);
end;

procedure TfmAdjDivForm.imgP3Click(Sender: TObject);
begin
  inherited;
  edP3.Text := Format('%f', [GetE24(CheckField(edP3))]);
end;

procedure TfmAdjDivForm.imgP2Click(Sender: TObject);
begin
  inherited;
  edP2.Text := Format('%f', [GetE24(CheckField(edP2))]);
end;

procedure TfmAdjDivForm.imgR3Click(Sender: TObject);
begin
  inherited;
  exit;
  
  LoadPictureFromRes(imgR1.Picture, 'R1');
  LoadPictureFromRes(imgR2.Picture, 'R2');
  LoadPictureFromRes(imgR3.Picture, 'R3S');
  LoadPictureFromRes(imgUin.Picture, 'UIN');
  LoadPictureFromRes(imgUout.Picture, 'UOUT');
  SetLabels('P1',getString('#global\Uin'),getString('#global\volt'));
  SetLabels('P2','R1',getString('#global\Ohm'));
  SetLabels('P4','R2',getString('#global\Ohm'));
  SetLabels('P3', Format('%s(%s)', [getString('#global\Uout'), getString('#global\min')]), getString('#global\volt'));
  SetLabels('P5', Format('%s(%s)', [getString('#global\Uout'), getString('#global\max')]), getString('#global\volt'));
  SetLabels('Result','R3',getString('#global\Ohm'));
  edP5.Visible := true;
  laP5.Visible := true;

  FObjectIndex := otRAdj;
end;

class function TfmAdjDivForm.CalcFriendlyName: string;
begin
  Result := 'Adjusted voltage divider';
end;

class function TfmAdjDivForm.RunKey: string;
begin
  Result := 'adjdiv';
end;

class procedure TfmAdjDivForm.InvokeCalc;
begin
  Application.CreateForm(TfmAdjDivForm, fmAdjDivForm);
  inherited;
end;

initialization
  RegisterCalc(TfmAdjDivForm);

end.
